# -*- coding: utf-8 -*-
"""
@Time    : 2024/7/16 16:35 
@Author  : ZhangShenao 
@File    : file_context_manager_by_class.py
@Desc    : 基于类实现,自定义文件上下文管理器

使用类来创建上下文管理器时,必须保证这个类中包含__enter__和__exit__这两个方法
__enter__方法在进入上下文管理器时自动调用,用于返回需要被管理的资源
__exit__方法在退出上下文管理器时自动调用,用于处理资源的释放和清理相关操作
"""


class FileContextManager:
    """文件上下文管理器类"""

    def __init__(self, file_path: str, mode: str = 'r'):
        """
        构造函数
        :param self:
        :param file_path: 文件路径
        :param mode: 打开文件的模式
        """

        # 初始化文件属性
        print('calling __init__ method')
        self.__file_path = file_path
        self.__mode = mode
        self.file = None

    def __enter__(self):
        """
        进入上下文管理器,返回需要被管理的资源
        :return: 管理器所管理的资源
        """

        print('calling __enter__ method')

        # 打开文件并返回文件资源
        self.file = open(self.__file_path, self.__mode)
        return self.file

    def __exit__(self, exc_type, exc_val, exc_tb):
        """
        退出上下文管理器,进行资源释放操作
        :param exc_type: 异常类型
        :param exc_val: 异常值
        :param exc_tb: 异常
        """

        print('calling __exit__ method')

        # 处理相关异常
        if exc_type is not None:
            print('handle exception')
            print(f'exc_type = {exc_type}, exc_val = {exc_val}')
            print(f'exception traceback: {exc_tb}')

        # 释放文件资源
        if self.file is not None:
            self.file.close()

        # 返回True,表示异常已经被捕获,该异常便不会再抛出
        return True


def write_file():
    # 使用自定义文件上下文管理器
    with FileContextManager('b.txt', 'a') as f:
        print('open file success')

        # 向文件写入内容
        f.write('hello world\n')


def write_file_error():
    """模拟写入文件异常"""
    with FileContextManager('b.txt', 'a') as f:
        raise Exception('write file error').with_traceback(None)


if __name__ == '__main__':
    # write_file()

    write_file_error()
